package com.example.rizhaoscienceandtechnologymuseum.Utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.hardware.Camera;
import android.media.FaceDetector;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import com.common.pos.api.util.PosUtil;

import java.io.IOException;

/**
 * Created by yubo on 2015/9/20.
 */
public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {

    private Context context;
    private Camera camera;
    private FaceView faceView;
    private int mWidth = 640; //值只能在摄像头支持的范围选择800X600 1280X720
    private int mHeight = 480;//值越大，识别距离越远，耗时越大
    private OnFaceDetectedListener onFaceDetectedListener;
    private int width = 640, height = 480;
    private int hwColorCamera = 0;
    private int displayOrient = 270;
    private FaceStock faceStock;
    private boolean isOpenAutoLigthCheck = false;
    private int monitorCycle = 10;//分钟
    private int lightValue = 30;//光亮边界值
    //上次记录的索引
    int darkIndex = 0;
    //一个历史记录的数组，255是代表亮度最大值
    long[] darkList = new long[]{255, 255, 255, 255};
    //扫描间隔
    int waitScanTime = 300;
    //亮度低的阀值
    int darkValue = 60;
    long lastRecordTime = System.currentTimeMillis();

    /**
     * 预览时Frame的计数器
     */
    private static int frameCount = 0;
    private setfaecCut faceCut;
    private Bitmap bitmapCut;


    public CameraView(Context context) {
        super(context);
        init(context);
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        this.context = context;
//        setZOrderOnTop(true);
//        getHolder().setFormat(PixelFormat.TRANSLUCENT);
        getHolder().addCallback(this);
    }

    public void setFaceView(FaceView faceView) {
        if (faceView != null) {
            this.faceView = faceView;
            float scaleRate = mHeight * 1.0f / getScreenSize().x;
            faceView.setScaleRate(scaleRate);
            faceView.setVisibility(View.VISIBLE);
        }
    }

    public void setFaceStock(FaceStock faceStock, Boolean isOpenAutoLigthCheck, int monitorCycle, int lightValue) {
        this.faceStock = faceStock;
        this.isOpenAutoLigthCheck = isOpenAutoLigthCheck;
        this.monitorCycle = monitorCycle;
        this.lightValue = lightValue;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {

            camera = Camera.open(0);
            Camera.Parameters parameters = camera.getParameters();
            parameters.setPreviewSize(mWidth, mHeight);
            camera.setParameters(parameters);
            if (camera != null) {
                camera.setDisplayOrientation((hwColorCamera * 180 + displayOrient) % 360);
                camera.setPreviewDisplay(holder);
                camera.setPreviewCallback(this);
                holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (camera != null) {
            ViewGroup.LayoutParams params = getLayoutParams();
            Point point = getScreenSize();
            /*params.width = point.x;
            params.height = mWidth * point.x / mHeight;*/
            params.width = 650;
            params.height = 875;
            setLayoutParams(params);
            if (faceView != null) {
                faceView.setLayoutParams(params);
            }
            camera.startPreview();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            try {
                camera.stopPreview();
                camera.setPreviewDisplay(null);
                camera.setPreviewCallback(null);
                camera.release();
                camera = null;
                Log.e("yk", "摄像头0被销毁");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取手机屏幕的尺寸
     *
     * @return
     */
    private Point getScreenSize() {
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(outMetrics);
        return new Point(outMetrics.widthPixels, outMetrics.heightPixels);
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        if (frameCount == Integer.MAX_VALUE) frameCount = 0;
        frameCount++;
        if (frameCount % 2 == 0) {
            detectFaces(ImageUtils.yuv2Jpeg(data, width, height), data);
        }
        if (isOpenAutoLigthCheck) {
            lightCheck(data);
        }
    }

    /**
     * 检测data数据中是否有人脸，这里需要先旋转一下图片，该方法执行在子线程中
     *
     * @param data
     */
    private void detectFaces(final byte[] data, final byte[] data2) {
        Bitmap bitmap = ImageUtils.rotateBitmap(BitmapFactory.decodeByteArray(data, 0, data.length), 90).copy(Bitmap.Config.RGB_565, true);

        FaceDetectorUtils.detectFace(bitmap, new FaceDetectorUtils.Callback() {
            @Override
            public void onFaceDetected(FaceDetector.Face[] faces, Bitmap bm, int faceNum) {  // 有人脸
                try {
                    bitmapCut = FaceCj.cutFace(bm, context);
                    faceCut.faecCut(bitmapCut);
                } catch (Exception e) {

                }
                faceView.setFaces(faces);
                if (faceStock.getColorListSize() < 5) {
                    faceStock.setColorList(data2);
                }


            }

            @Override
            public void onFaceNotDetected(Bitmap bm) {   //  没有人脸
                bm.recycle();
                if (faceView != null) {
                    faceView.clear();
                }
            }
        });
        bitmap.recycle();
    }

    public void setParams(boolean isOpenAutoLigthCheck, int monitor_cycle, int lightValue) {
        this.isOpenAutoLigthCheck = isOpenAutoLigthCheck;
        this.monitorCycle = monitor_cycle;
        this.lightValue = lightValue;
    }

    /**
     * 检测到人脸的监听器
     */
    public interface OnFaceDetectedListener {
        void onFaceDetected(int faces);
    }

    /**
     * 设置监听器，监听检测到人脸的动作
     */
    public void setOnFaceDetectedListener(OnFaceDetectedListener listener) {
        if (listener != null) {
            this.onFaceDetectedListener = listener;
        }
    }

    /**
     * 照片亮度检查
     */
    public void lightCheck(byte[] data) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastRecordTime < monitorCycle * 60 * 1000) {
            return;
        }
        lastRecordTime = currentTime;
        //像素点的总亮度
        long pixelLightCount = 0L;
        //像素点的总数
        long pixeCount = width * height;
        //采集步长，因为没有必要每个像素点都采集，可以跨一段采集一个，减少计算负担，必须大于等于1。
        int step = 10;
        //data.length - allCount * 1.5f的目的是判断图像格式是不是YUV420格式，只有是这种格式才相等
        //因为int整形与float浮点直接比较会出问题，所以这么比
        if (Math.abs(data.length - pixeCount * 1.5f) < 0.00001f) {
            for (int i = 0; i < pixeCount; i += step) {
                //如果直接加是不行的，因为data[i]记录的是色值并不是数值，byte的范围是+127到—128，
                // 而亮度FFFFFF是11111111是-127，所以这里需要先转为无符号unsigned long参考Byte.toUnsignedLong()
                pixelLightCount += ((long) data[i]) & 0xffL;
            }
            //平均亮度
            long cameraLight = pixelLightCount / (pixeCount / step);
            //更新历史记录
            int lightSize = darkList.length;
            darkList[darkIndex = darkIndex % lightSize] = cameraLight;
            darkIndex++;
            boolean isDarkEnv = true;
            //判断在时间范围waitScanTime * lightSize内是不是亮度过暗
            for (int i = 0; i < lightSize; i++) {
                Log.e("CameraActivity", "亮度" + i + " ： " + darkList[i]);
                if (darkList[i] > lightValue) {
                    isDarkEnv = false;
                }
            }
            Log.e("CameraActivity", "摄像头环境亮度为 ： " + cameraLight);
            Log.e("CameraActivity", "检测亮度 ： " + lightValue);
            //亮度过暗就提醒
            if (isDarkEnv) {
                Log.e("CameraActivity", "结果：环境暗");
                PosUtil.setLedPower(1);//打开
            } else {
                Log.e("CameraActivity", "结果：环境亮");
                PosUtil.setLedPower(0);//关闭
            }
        }
    }

    public interface setfaecCut {
        void faecCut(Bitmap bitmatCut);
    }

    public void setfaecCutListener(setfaecCut setfaecCut) {
        faceCut = setfaecCut;
    }
}